package two.chapter_1.c1_2;

import edu.princeton.cs.algs4.StdOut;

public abstract class Date {
    public Date(String date){
        this(parse(date,0),
                parse(date,1),
                parse(date,2));

    }
    private static int parse(String date,int index){
        return Integer.parseInt(date.split("/")[index]);
    }
    public Date(int month,int day,int year){
    }

    abstract int day();
    abstract int month();
    abstract int year();

    public static Date[]readDates(String[]dates){
        Date[] result=new Date[dates.length];
        for (int i=0;i<dates.length;i++){
            result[i]=new DefaultDate(dates[i]);
        }
        return result;
    }
    public static Date parse(String date){
        return new DefaultDate(date);
    }

    @Override
    public String toString() {
        return month()+"/"+day()+"/"+year();
    }

    public static void main(String [] args){
        int m=8;
        int d=9;
        int y=2018;
        Date date=new BitDate(m,d,y);
        StdOut.println(date);
    }


    private static class DefaultDate extends Date{
        private int month;
        private int day;
        private int year;
        public DefaultDate(String date){
            super(date);
        }
        public DefaultDate(int month, int day, int year) {
            super(month, day, year);
            this.month=month;
            this.day=day;
            this.year=year;
        }

        @Override
        int day() {
            return day;
        }

        @Override
        int month() {
            return month;
        }

        @Override
        int year() {
            return year;
        }


    }

    /**
     * 一个int类型的存储长度为32位。
     * 取后1-5位存储d的值，因为 0<1<=d<=31。即2的5次方
     * 取中间6-9位存储m的值，因为 0<1<=m<=12<15。即2的4次方
     * 剩下的10至31位存储y的值（int为有符号整数，32位为符号位）。
     *
     * 这是一个按位存储的算法。
     */
    private static class BitDate extends Date{
        private int value;
        public BitDate(int month, int day, int year) {
            super(month, day, year);
            value=year*512+month*32+day;//512/32=16
        }

        @Override
        int day() {
            return value%32;
        }

        @Override
        int month() {
            return (value/32)%16;
        }

        @Override
        int year() {
            return value/512;
        }
    }

    @Override
    public boolean equals(Object obj) {
        if (this==obj) return true;
        if (obj==null) return false;
        if (this.getClass()!=obj.getClass()) return false;
        Date that= (Date) obj;
        if (this.day() !=that.day()) return false;
        if (this.month() !=that.month()) return false;
        if (this.year() !=that.year()) return false;

        return true;

    }
}
